import java.util.concurrent.*;

/**
 * @author Dennis Li
 * @date 2020/9/27 18:10
 */
public class ConcurrentDemo {

    public static void main(String[] args) {
        // 排序排的是Key，而不是Value
        ThreadPoolExecutor service = new ThreadPoolExecutor(2, 2, 0L, TimeUnit.SECONDS, new LinkedBlockingDeque<>(1));

        service.execute(() -> System.out.println(1));
        service.execute(() -> System.out.println(1));
        service.execute(() -> System.out.println(1));

        service.shutdownNow();

        while (!service.isTerminated()) ;
        // 这里线程池状态被置为了Shutdown
        // 线程池关闭后再提交任务会执行拒绝策略
        service.execute(() -> System.out.println(1));
        service.execute(() -> System.out.println(1));
        service.execute(() -> System.out.println(1));
    }

    public static void main2(String[] args) throws ExecutionException, InterruptedException {
        outer:
        for (int i = 0; i < 3; i++) {
            inner:
            for (int j = 0; j < 5; j++) {
                if (j == 3) {
                    System.out.println(j);

                    break outer;
                }
            }
        }
        System.out.println("end");
        // Callable 使用
        // 第一种，用FutureTask封装Callable，交由Thread执行FutureTask，再通过主线程的阻塞方法get获取值
        FutureTask<Integer> task = new FutureTask<>(new CallableDemo());

        new Thread(task).start();

        System.out.println(task.get());

        // 第二种，定义一个线程池，提交Callable任务
        ExecutorService single = Executors.newSingleThreadExecutor();

        // 注意这里不能传入FutureTask，因为它是实现的Runnable接口，而不是Callable接口，会被当做Runnable进行处理
        Future<?> future = single.submit(new CallableDemo());

        ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 2, 0L, TimeUnit.SECONDS, new LinkedBlockingDeque<>(1));

        for (int i = 0; i < 3; i++) {
            executor.execute(task);
        }

        System.out.println(future.get());

        single.shutdown();
    }

    static class CallableDemo implements Callable<Integer> {

        @Override
        public Integer call() throws Exception {
            Thread.sleep(1000);
            return 1;
        }

    }

}
